/* NavigationEvent.java

	Purpose:

	Description:

	History:
		Tue Sep 25 12:12:10 CST 2018, Created by rudyhuang

Copyright (C) 2018 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zuti;

import java.util.List;

import org.zkoss.zuti.zul.TemplateBasedShadowElement;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.Binder;
import org.zkoss.bind.Phase;
import org.zkoss.bind.PhaseListener;
import org.zkoss.bind.impl.BinderImpl;
import org.zkoss.bind.sys.BinderCtrl;
import org.zkoss.bind.sys.Binding;
import org.zkoss.bind.sys.ReferenceBinding;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.ShadowElement;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;

/**
 * Defines an event that encapsulates changes to a navigation model.
 *
 * @author rudyhuang
 * @since 8.6.0
 */
public class BindPhaseListener implements PhaseListener {

    public void prePhase(Phase phase, BindContext ctx) {
    }

    public void postPhase(Phase phase, BindContext ctx) {
        switch (phase) {
            case INITIAL_BINDING:
                if (ctx.getComponent() instanceof ShadowElement) {
                    Binder binder = ctx.getBinder();
                    if (binder instanceof BinderImpl) {
                        BinderImpl binderImpl = (BinderImpl) binder;
                        Component shadow = ctx.getComponent();
                        List<Binding> list = binderImpl.getBindings(shadow).get(ctx.getCommandName());
                        boolean shallHandle = false;
                        for (Binding binding : list) {
                            if (binding instanceof ReferenceBinding) {
                                shallHandle = true;
                                break;
                            }
                        }
                        if (shallHandle) {
                            Execution current = Executions.getCurrent();
                            final String key = Phase.LOAD_BINDING + shadow.getUuid();
                            if (!current.hasAttribute(key)) {
                                current.setAttribute(key, Boolean.TRUE);
                                ctx.setAttribute(shadow.getUuid(), key); // save it for clean up later
                                Events.postEvent(10000, TemplateBasedShadowElement.ON_BINDING_READY, shadow, ctx); // post at the end of the event loop
                            }
                        }
                    }
                }
                break;
            case LOAD_BINDING:
            case SAVE_BINDING:
                if (ctx.getComponent() instanceof ShadowElement) {
                    Component shadow = ctx.getComponent();
                    Execution current = Executions.getCurrent();
                    final String key = phase + shadow.getUuid();
                    if (!current.hasAttribute(key)) {
                        current.setAttribute(key, Boolean.TRUE);
                        ctx.setAttribute(shadow.getUuid(), key); // save it for clean up later
                        if (shadow.getAttribute(BinderCtrl.BINDRENDERING, true) != null) {
                            Events.sendEvent(new Event(TemplateBasedShadowElement.ON_BINDING_READY, shadow, ctx));
                        } else {
                            Events.postEvent(10000, TemplateBasedShadowElement.ON_BINDING_READY, shadow, ctx); // ZK-4221: change to send ON_BINDING_READY
                        }

                    }
                }
                break;
            default:
                // do nothing;
        }
    }

}
